-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add erasable phantom classes (old) #1408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Sounds interesting, but lacks any kind of description. What are these phantom types? Why would one want to use them? |
For now the PR is just for testing purposes. I will add a full description once it is more mature. The basic idea is to have parameters/field that will get erased (term wise). This will be needed for efficient implementation of implicit evidences for the capability based effect system. |
In that case we should mark the title of the PR with [WIP]. I think the "in progress" label is not specific enough. |
7fc880b
to
36a4048
Compare
/rebuild |
f463cb0
to
d0793e7
Compare
3be5349
to
0ed4e3c
Compare
487e143
to
9c83c67
Compare
ae0560d
to
7429b27
Compare
7429b27
to
d51ea40
Compare
d51ea40
to
74bb24e
Compare
In this commit phantom types are defined and implemented. Only a minimal version of phantom term erasure is included. Phantom types are in latices outside of the normal `Any`/`Nothing` type lattice. A new phantom lattice can be defined by extending an `object` with `scala.Phantom`. This trait defines synthetic members * `protected final trait Any` where this `Any` does not extends `scala.Any` * `protected final abstract class Nothing extends this.Any` * `protected final def assume[P >: this.Nothing <: this.Any]: P` A phantom lattice object can expose any of the phantom members (`Any`, `Nothing`, `assume`) using an alias but it is not required. Restriction on lattices: * Types from different lattice can not be mixed using `&` or `|` types. * Type parameters must be bounded by types in a single lattice. Phantom type erasure (minimalistic): * Type references `Phantom.Any` and `Phantom.Nothing` are erased to `dotty.runtime.ErasedPhantom` * `Phantom.assume[P]` is erased to `null.asInstanceOf[P]` * `Phantom` is erased to `dotty.runtime.ErasedPhantomLattice`, removing the members of `Phantom`
This commit removes arguments and parameter of phantom type from all applications. Arguments are evaluated before the application in case they have side effects. ``` def foo(i: Int, p: SomePhantom) = ??? foo(42, { println("hello"); getSomePhantom }) ``` becomes ``` def foo(i: Int) = ??? val x$0 = 42 val x$1 = { println("hello"); getSomePhantom } foo(x$0) ``` Note that now `def foo(i: Int)` and def `foo(i: Int, p: SomePhantom)` erase to the same signature. Tests for this commit where added in `Extra tests for Phantoms 1`, they where back ported as the semantics and runtime is not affected.
Erase all `val` and `var` of phantom type. `lazy val` are not transformed as their expansion is done in the backend. Erasure: * Assignments are replaced by their RHS * Local `val` and `var` definitions are replaced by their RHS * Fields are removed * Getters return `null.asInstanceOf[dotty.runtime.ErasedPhantom]` Tests for this commit where added in `Extra tests for Phantoms 2`, they where back ported as the semantics and runtime is not affected.
74bb24e
to
946a331
Compare
This PR is outdated. It was split into smaller parts: |
Implementation details: https://gist.github.com/nicolasstucki/572c3ee016e966c26491990c6eac8b80